package de.godlike.fxbox.presentation;

import java.awt.Dimension;
import java.awt.Toolkit;

import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IVirtualBox;
import org.virtualbox_4_1.VirtualBoxManager;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import de.godlike.fxbox.persistence.dao.ServerConfigDoa;
import de.godlike.fxbox.persistence.entity.ServerConfig;

public class FxboxMainWindow extends Application {
	private final GridPane centerCommonPaneContent = new GridPane();
	private final InteractionHandler iaHandler = new InteractionHandler();
	private static FxboxMainWindow me;
	private BorderPane root;
	private Node topNode;
	private Node leftNode;
	private Node centerNode;


	public BorderPane getRoot() {
		return root;
	}

	public void setRoot(BorderPane root) {
		this.root = root;
	}

	public Node getTopNode() {
		return topNode;
	}

	public void setTopNode(Node topNode) {
		this.topNode = topNode;
	}

	public Node getLeftNode() {
		return leftNode;
	}

	public void setLeftNode(Node leftNode) {
		this.leftNode = leftNode;
	}

	public Node getCenterNode() {
		return centerNode;
	}

	public void setCenterNode(Node centerNode) {
		this.centerNode = centerNode;
	}
	
	public static FxboxMainWindow getInstance() {
		return me;
	}

	/*
	 * IDs der UI Elemente
	 */
	public static final String NEW_HOST_SYSTEM_ID = "NEW_HOST_SYSTEM";

	private void setCenterCommonPaneContent() {
		this.centerCommonPaneContent.add(new Label("Name:"), 0, 0);
		this.centerCommonPaneContent.add(new Label("OS-Typ:"), 0, 1);
	}

	private Node buildTop() {
		VBox vbox = new VBox();

		/*
		 * Application Menu
		 */
		final Menu menu1 = new Menu("Datei");
		final Menu menu2 = new Menu("Maschine");
		final Menu menu3 = new Menu("Hilfe");

		menu1.getItems().add(new MenuItem("Globale Einstellungen..."));
		MenuItem closeMenu = new MenuItem("Beenden");
		closeMenu.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {
				System.exit(0);
			}
		});
		menu1.getItems().add(closeMenu);

		menu2.getItems().add(new MenuItem("Neu..."));
		menu2.getItems().add(new MenuItem("Hinzufügen..."));

		menu3.getItems().add(new MenuItem("Inhalt..."));

		MenuBar menuBar = new MenuBar();
		menuBar.getMenus().addAll(menu1, menu2, menu3);

		/*
		 * Icon Menu, oder wie man es sonst nennt
		 */
		HBox buttonBox = new HBox();
		/*
		 * Neues Host System Hinzufügen
		 */
		Button newHostSystem = new Button("Neu");
		newHostSystem.setOnAction(iaHandler);
		newHostSystem.setId(FxboxMainWindow.NEW_HOST_SYSTEM_ID);
		buttonBox.getChildren().add(newHostSystem);
		/*
		 * Einstellungen eines Gastsystems ändern
		 */
		Button modifyGuestProperties = new Button("Ändern");
		modifyGuestProperties.setOnAction(iaHandler);
		buttonBox.getChildren().add(modifyGuestProperties);
		/*
		 * Gastsystem starten
		 */
		Button startGuestSystem = new Button("Starten");
		startGuestSystem.setOnAction(iaHandler);
		buttonBox.getChildren().add(startGuestSystem);
		/*
		 * Gastsystem schließen und Änderungen verwerfen falls vorhanden
		 */
		Button discardGuestSystem = new Button("Verwerfen");
		discardGuestSystem.setOnAction(iaHandler);
		buttonBox.getChildren().add(discardGuestSystem);

		vbox.getChildren().add(menuBar);
		vbox.getChildren().add(buttonBox);

		return vbox;
	}

	private Node buildLeft() {
		// TODO: Irgendwie sieht es nicht vernünftig aus, aber funktoniert
		ListView<TitledPane> serverHostSelection = new ListView<TitledPane>();
		ServerConfigDoa serverDoa = ServerConfigDoa.getInstance();

		for (ServerConfig server : serverDoa.getAllServer()) {
			VBox guestSystemContainerBox = new VBox();

			VirtualBoxManager mgr = VirtualBoxManager.createInstance(null);
			mgr.connect(server.getUrl(), server.getUsername(),server.getPassword());
			IVirtualBox instance = mgr.getVBox();
			for (IMachine nodeSystem : instance.getMachines()) {
				guestSystemContainerBox.getChildren().add(new Button(nodeSystem.getName()));
			}

			TitledPane hostView = new TitledPane(server.getDisplayName(),
					guestSystemContainerBox);
			hostView.setExpanded(false);

			serverHostSelection.getItems().add(hostView);
		}

		return serverHostSelection;
	}

	private Node buildCenter() {
		TabPane tabPane = new TabPane();
		tabPane.setPrefSize(400, 400);
		tabPane.setSide(Side.TOP);
		tabPane.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);

		Tab detailTab = new Tab("Details");
		GridPane detailTabPane = new GridPane();
		detailTabPane.setHgap(10);
		detailTabPane.setVgap(10);
		detailTabPane.setPadding(new Insets(0, 0, 0, 10));
		detailTabPane.setGridLinesVisible(true);
		ColumnConstraints column1 = new ColumnConstraints();
		column1.setPercentWidth(30);
		ColumnConstraints column2 = new ColumnConstraints();
		column2.setPercentWidth(70);
		detailTabPane.getColumnConstraints().addAll(column1, column2);
		detailTab.setContent(detailTabPane);
		TitledPane commonTile = new TitledPane();
		commonTile.setText("Allgemein");
		this.setCenterCommonPaneContent();
		commonTile.setContent(this.centerCommonPaneContent);
		detailTabPane.add(commonTile, 0, 0);
		TitledPane systemTile = new TitledPane();
		systemTile.setText("System");
		detailTabPane.add(systemTile, 0, 1);

		TitledPane previewTile = new TitledPane();
		previewTile.setText("Vorschau");
		detailTabPane.add(previewTile, 1, 0, 1, 2);

		Tab snapshotTab = new Tab("Sicherungspunkte");
		tabPane.getTabs().addAll(detailTab, snapshotTab);
		return tabPane;
	}

	public void start(Stage primaryStage) throws Exception {
		me = this;
		root = new BorderPane();
		

		// TODO: Beides etwa 3/4 beim starten
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		Scene scene = new Scene(root, screen.getWidth() / 2,
				screen.getHeight() / 2);

		this.setTopNode(this.buildTop());
		this.setLeftNode(this.buildLeft());
		this.setCenterNode(this.buildCenter());

		this.getRoot().setTop(this.getTopNode());
		this.getRoot().setLeft(this.getLeftNode());
		this.getRoot().setCenter(this.getCenterNode());
		primaryStage.setScene(scene);
		primaryStage.show();
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		launch(args);
	}

}
